package cn.sjx.modules.nbiot.business.impl;

import cn.sjx.modules.nbiot.business.IBusinessServer;
import cn.sjx.modules.nbiot.business.IGeomagneticUdpBusinessHandler;
import cn.sjx.modules.nbiot.entity.common.AckEnum;
import cn.sjx.modules.nbiot.entity.common.IotProtocolConstants;
import cn.sjx.modules.nbiot.entity.receive.IotProtocolReceive_0x21;
import cn.sjx.modules.nbiot.entity.send.IotProtocolSend_0x77;
import cn.sjx.modules.nbiot.util.CRC16Util;
import cn.sjx.modules.nbiot.util.PropertiesUtil;
import cn.sjx.modules.nbiot.util.SpringBeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.HexUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;

/**
 * 地磁心跳包报文
 * 如果需要心跳包，需联系相关销售人员提出要求，出厂前可进行配置，如果未配置有心跳包功能已出厂的设备，无法进行配置修改。
 * 地磁心跳包报文结构说明 (0x21) 服务实现
 *
 * @Author: sjx
 * @Date: 2019年08月30日 0030 15:23:11
 */
public class IotProtocolBusinessServerImpl_0x21 implements IBusinessServer<IotProtocolReceive_0x21> {

    private static final Log logger = LogFactory.get();

    /**
     * 获取是否调试模式的值
     */
    private static final Boolean NB_IOT_IS_DEBUGGER = PropertiesUtil.getBooleanValueByKey(IotProtocolConstants.NB_IOT_IS_DEBUGGER_FLAG);

    private IGeomagneticUdpBusinessHandler geomagneticUdpBusinessHandler = null;

    public IotProtocolBusinessServerImpl_0x21() {
        // 非调试模式时，手动注入geomagneticUdpBusiness属性
        if (NB_IOT_IS_DEBUGGER != null && !NB_IOT_IS_DEBUGGER) {
            this.geomagneticUdpBusinessHandler = SpringBeanUtil.getBean("geomagneticUdpBusinessHandler", IGeomagneticUdpBusinessHandler.class);
        }
    }

    @Override
    public byte[] businessHandler(IotProtocolReceive_0x21 receiveMsg, byte[] receiveMsgByte) throws Exception {
        // 默认返回其它错误
        AckEnum ackEnum = AckEnum.ERROR_OTHER;

        try {
            // 从原生报文中 获取除CRC校验码外的数据
            byte[] crcCodeByte = new byte[receiveMsgByte.length - 2];
            System.arraycopy(receiveMsgByte, 0, crcCodeByte, 0, (receiveMsgByte.length - 2));

            if (!CRC16Util.equalsCrc(receiveMsg.getCrcCode(), crcCodeByte)) {
                // 0x17：CRC 验证失败
                ackEnum = AckEnum.CRC_VERIFICATION_FAILED;
            } else {
                // 业务处理
                if (NB_IOT_IS_DEBUGGER != null && !NB_IOT_IS_DEBUGGER) {
                    ackEnum = geomagneticUdpBusinessHandler.handler(receiveMsg, HexUtil.encodeHexStr(receiveMsgByte, false));
                } else {
                    ackEnum = AckEnum.SUCCESSFUL;
                }
            }
        } catch (Exception e) {
            // 0x30：未知错误
            ackEnum = AckEnum.UNKNOWN_MISTAKE;
        } finally {
            return new IotProtocolSend_0x77().setAck(ackEnum)
                    .setParkCount(receiveMsg.getPackCount())
                    .setTime(HexUtil.decodeHex(DateUtil.format(DateUtil.date(), DatePattern.PURE_DATETIME_PATTERN)))
                    .setCommand((byte) 0x00)
                    .setReserverd(0)
                    .encode();
        }
    }
}
